import { useCameraPlayer } from '@/contexts/CameraPlayerContext';
import { post } from '@/utils/request';
import HikCameraSDK from '@/utils/hikCamera';
import type { CameraSource } from '@/types/camera';
import { get } from 'lodash';

// 海康威视 JSPlugin 类型定义（根据 H5player 2.5.1 文档）
interface JSPluginEvents {
  windowEventSelect?: (index: number) => void;
  pluginErrorHandler?: (index: number, iErrorCode: number, oError: string) => void;
  windowEventOver?: (index: number) => void;
  windowEventOut?: (index: number) => void;
  windowEventUp?: (index: number) => void;
  windowFullCcreenChange?: (bFull: boolean) => void;
  firstFrameDisplay?: (index: number, iWidth: number, iHeight: number) => void;
  performanceLack?: () => void;
  StreamEnd?: (index: number) => void;
  InterruptStream?: (iWndIndex: number, interruptTime: number) => void;
  talkPluginErrorHandler?: (iErrorCode: number, oErrorInfo: string) => void;
  ThumbnailsEvent?: (iWndIndex: number, eventType: number, eventCode: number) => void;
}

interface JSPluginConfig {
  szId: string; // 父窗口id，需要英文字母开头 必填
  szBasePath: string; // 必填,与h5player.min.js的引用目录一致
  mseWorkerEnable?: boolean; // 是否开启多线程解码
  bSupporDoubleClickFull?: boolean; // 是否支持双击全屏
  iWidth?: number; // 窗口宽度
  iHeight?: number; // 窗口高度
  iMaxSplit?: number; // 最大分屏数，默认最大分屏4*4
  iCurrentSplit?: number; // 当前分屏数
  oStyle?: {
    borderSelect?: string; // 选中窗口边框颜色，默认#FFCC00
  };
}

interface HikJSPlugin {
  JS_SetWindowControlCallback(events: JSPluginEvents): Promise<void>;
  JS_Play(
    url: string,
    config: {
      playURL: string;
      mode?: number; // 0=普通模式; 1=高级模式 默认为0
      PlayBackMode?: number; // 1：绝对时间正放; 3 绝对时间倒放 默认为1
      keepDecoder?: number; // 0:回收解码资源; 1:不回收解码资源
      token?: string; // 安全认证token
    },
    windowIndex: number,
    startTime?: string, // 回放开始时间，格式：2021-06-29T00:00:00Z
    endTime?: string // 回放结束时间，格式：2021-06-29T00:00:00Z
  ): Promise<void>;
  JS_Stop(windowIndex: number): Promise<void>;
  JS_StopRealPlayAll(): Promise<void>;
  JS_OpenSound(windowIndex?: number): Promise<void>;
  JS_CloseSound(windowIndex?: number): Promise<void>;
  JS_SetVolume(windowIndex: number, volumn: number): Promise<void>;
  JS_GetVolume(windowIndex: number): Promise<number>;
  JS_StartSaveEx(windowIndex: number, fileName: string, idstType: number): Promise<void>;
  JS_StopSave(windowIndex: number): Promise<void>;
  JS_CapturePicture(windowIndex: number, fileName: string, fileType: string, callback?: (imageData: string) => void): Promise<void>;
  JS_Pause(windowIndex: number): Promise<void>;
  JS_Resume(windowIndex: number, bForward?: boolean): Promise<void>;
  JS_ArrangeWindow(splitNum: number): Promise<void>;
  JS_SelectWnd(windowIndex: number): Promise<void>;
  JS_FullScreenDisplay(isFull: boolean): Promise<void>;
  JS_FullScreenSingle(windowIndex: number): Promise<void>;
  JS_Resize(iWidth?: number, iHeight?: number): Promise<void>;
  JS_GetOSDTime(windowIndex: number): Promise<number>;
  JS_GetVideoInfo(windowIndex: number): Promise<any>;
  JS_SetConnectTimeOut(windowIndex: number, nTime: number): Promise<void>;
  JS_Fast(windowIndex: number): Promise<number>;
  JS_Slow(windowIndex: number): Promise<number>;
  JS_Seek(windowIndex: number, stratTime: string, endTime: string): Promise<void>;
  JS_FrameForward(windowIndex: number): Promise<void>;
  JS_FrameBack(windowIndex: number): Promise<void>;
  JS_EnableZoom(windowIndex?: number): Promise<void>;
  JS_DisableZoom(windowIndex?: number): Promise<void>;
  JS_Speed(windowIndex: number, rate: number): Promise<number>;
  JS_Rotate(windowIndex: number, degree: number): Promise<void>;
  JS_Scale(windowIndex: number, ratio: string): Promise<void>;
  JS_ScaleCancel(windowIndex: number): Promise<void>;
}

declare global {
  interface Window {
    JSPlugin?: new (config: JSPluginConfig) => HikJSPlugin;
  }
}

const useHikCameraPlayer = () => {
  const {
    state, setPlayer, setSelectedIndex, togglePlayer,
  } = useCameraPlayer();


  const setAllFullScreen = (enable: boolean = true) => {
    if (!state.player) return;
    state.player.JS_FullScreenDisplay(enable);
  }

  const setSelectedWindowFullScreen = () => {
    if (!state.player) return;
    state.player.JS_FullScreenSingle(state.selectedIndex);
  }

  async function testLocalProxyCameraRequest(cameraCode: string) {
    const hikCamera = HikCameraSDK.getInstance();
    const info = hikCamera.postSign({
      method: 'POST',
      url: '/artemis/api/video/v1/cameras/previewURLs',
    });

    const reqParam = {
      "cameraIndexCode": cameraCode,
      "streamType": 0,
      "protocol": "ws",
      "transmode": 1,
      "expand": "transcode=0"
    };

    const res = await post('/hik_camera/artemis/api/video/v1/cameras/previewURLs', reqParam, {
      dynamicBaseURL: '',
      headers: Object.fromEntries(info.headers),
    });

    let playUrl = '';

    if (res.code === '0') {
      playUrl = res.data.url;
    }
    return playUrl;
  }

  const playCamera = async (camera: CameraSource) => {
    const cameraCode = camera.cameraIndexCode;
    // const videoUrl = 'ws://191.244.13.51:6014/proxy/191.244.13.51:559/openUrl/XJhMNHy';
    const videoUrl = await testLocalProxyCameraRequest(cameraCode);

    if (!videoUrl) {
      console.error('海康平台-获取视频地址失败');
      message.error('获取视频地址失败');
      return;
    }

    const player = state.player || get(window, 'hikPlayer', null);
    if (!player) return;

    const targetIndex = state.selectedIndex;
    console.log('待播放视频的信息', targetIndex, videoUrl);

    player.JS_Play(videoUrl, {
      playUrl: videoUrl,
      mode: 0,
      keepDecoder: 0,
      token: ''
    }, targetIndex)
    player.JS_SelectWnd(targetIndex)
  }
  const play = (camera: CameraSource) => {
    if (!state.visible) {
      togglePlayer();

      setTimeout(() => {
        playCamera(camera);
      }, 500)
    } else {
      playCamera(camera);
    }
  }

  const stopPlay = () => {
    const player = state.player || get(window, 'hikPlayer', null);
    if (!state.visible || !player) return;
    player.JS_Stop(state.selectedIndex);
  }

  const stopAllPlay = () => {
    const player = state.player || get(window, 'hikPlayer', null);
    if (!state.visible || !player) return;
    player.JS_StopRealPlayAll();
  }

  const changeLayout = (splitNum: number) => {
    const player = state.player || get(window, 'hikPlayer', null);
    if (!state.visible || !player) return;
    player.JS_ArrangeWindow(splitNum);
  }

  return {
    state,
    setPlayer,
    setSelectedIndex,
    setAllFullScreen,
    setSelectedWindowFullScreen,
    play,
    stopPlay,
    stopAllPlay,
    changeLayout,
    togglePlayer,
  };
};

export default useHikCameraPlayer;
